/*
 * Copyright (C) 2009-2011 Knowings
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License version 3
 * as published by the Free Software Foundation.
 *

 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */
package com.knowings.tbs;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import com.knowings.tbs.io.UnsupportedFormatException;
import com.knowings.tbs.operation.*;
import com.knowings.tbs.permission.PermissionException;
import com.knowings.tbs.query.ITraceQuery;
import com.knowings.tbs.query.QueryRuntimeException;
import com.knowings.tbs.trace.*;
import com.knowings.tbs.transformation.ITransformation;
import com.knowings.tbs.transformation.ITransformationExecution;
import com.knowings.tbs.transformation.TransformationRuntimeException;

/**
 * Interface describing Trace Repository compliance level 2 features.
 * 
 * @author privarola
 */
public interface ILevel2Features {
  /**
   * Method retrieving a list of description containers for the accessible stored trace queries.
   * @return a List object containing the descriptions.
   */
  public List<IOperationDescriptor> getTraceQueryDescriptors();

  /**
   * Method retrieving a trace query regarding a given uid.
   * @param uid a String object identifying the requested query by its UID. This shouldn't be null.
   * @return an ITraceQuery object which uid is equal to the given argument. If this one was null or not bounded 
   * to this trace repository, then null is returned.//FIXME : irrelevant behaviour regarding the NoSuchObjectException.
   * @throws NoSuchObjectException if the uid does not match any known in the current workspace
   * @throws PermissionException if the connected user does not have read privileges on the matching trace query
   */
  public ITraceQuery getTraceQuery(String uid) throws PermissionException, NoSuchObjectException;

  /**
   * Method adding a trace query to the Trace Repository.
   * All related parameter definitions will also be created in the trace repository.
   * If specified the given query UID will be ignored and a new one will be generated.
   * @param query an ITraceQuery object representing the trace query to add.
   * @return the UID of the newly added query
   * @throws PermissionException if the connected user does not have the right to add a query
   */
  public String addTraceQuery(ITraceQuery query) throws PermissionException;

  /**
   * Method updating an existing trace query in the Trace Repository.
   * All existing parameter definitions may be removed if they are not referenced any more. 
   * @param query a ITraceQuery object representing the query to update; it must have a known UID.
   * @throws NoSuchObjectException if the query uid does not match any known in the current workspace
   * @throws PermissionException if the current user does not have the right to modify this query
   */
  public void updateTraceQuery(ITraceQuery query) throws NoSuchObjectException, PermissionException;

  /**
   * Method deleting an existing trace query from the Trace Repository.
   * @param uid the UID of an existing trace query
   * @throws NoSuchObjectException if the query uid does not match any known in the current workspace
   * @throws PermissionException if the current user does not have the right to delete this query
   */
  public void deleteTraceQuery(String uid) throws NoSuchObjectException, PermissionException;

  /**
   * Method retrieving a list of object as the results of a stored trace query executed on the fusion of several traces
   * @param trace_uids the uids of the traces to be taken into account (and merged) as data source for the query
   * @param query_uid the UID of the stored query to be executed
   * @param parameters a map containing parameter names as keys and parameter values as values
   * @param query_parameters a bunch of key/value parameters that are supported to the query engine to refine its execution.<br>
   *    It can be null or empty if no refinements are supplied.<br>
   *    //TODO documents about the possible keys to supply. 
   * @return a List of object containing the results of the given query
   * @throws NoSuchObjectException if the query UID is not found or if any of the source trace UID is not found
   * @throws PermissionException if the connected user does not have the right to access a source trace or the query
   * @throws MissingParameterException if a query mandatory parameter is not given in the parameters map
   * @throws InvalidParameterException if a query parameter does not have the expected type
   * @throws UnsupportedLanguageException if the query language is not supported
   * @throws IncompatibleTemporalDomainsException if a the source traces does not share the same temporal domain
   * @throws QueryRuntimeException if the query fails due to a syntax problem or internal error
   */
  public List<Object> executeQuery(String[] trace_uids, String query_uid, Map<String, Serializable> parameters,
      Map<String, Serializable> query_parameters) throws NoSuchObjectException, PermissionException,
      UnsupportedLanguageException, MissingParameterException, InvalidParameterException,
      IncompatibleTemporalDomainsException, QueryRuntimeException;

  /**
   * Method retrieving a list of description containers for the accessible stored transformations.
   * @return a List object containing the descriptions.
   */
  public List<IOperationDescriptor> getTransformationsDescriptors();

  /**
   * Method retrieving a transformation regarding a given uid.
   * @param uid a String object representing the given uid. This shouldn't be null.
   * @return an ITransformation object which uid is equal to the given argument. If this one was null or not bounded 
   * to this trace repository, then null is returned.
   * @throws NoSuchObjectException if the uid does not match any known in the current workspace
   * @throws PermissionException if the connected user does not have read privileges on the matching transformation
   */
  public ITransformation getTransformation(String uid) throws PermissionException, NoSuchObjectException;

  /**
   * Method adding a transformation to the Trace Repository.
   * All related parameter definitions will also be created in the trace repository.
   * If specified the given transformation UID will be ignored and a new one will be generated.
   * @param transformation an ITransformation object representing the transformation to add.
   * @return the UID of the newly added transformation
   * @throws PermissionException if the connected user does not have the right to add a transformation
   */
  public String addTransformation(ITransformation transformation) throws PermissionException;

  /**
   * Method updating an existing transformation in the Trace Repository.
   * All existing parameter definitions may be removed if they are not referenced any more. 
   * The referencing <code>ITransformationExecution</code> instances will be marked as obsolete.
   * @param transformation a ITransformation object representing the transformation to update; it must have a known UID.
   * @throws NoSuchObjectException if the transformation uid does not match any known in the current workspace
   * @throws PermissionException if the connected user does not have the right to modify this transformation
   */
  public void updateTransformation(ITransformation transformation) throws NoSuchObjectException, PermissionException;

  /**
   * Method deleting an existing transformation from the Trace Repository.
   * The referencing <code>ITransformationExecution</code> instances will be marked as obsolete.
   * @param uid a {@link String} object representing the uid.
   * @throws NoSuchObjectException if the transformation uid does not match any known in the current workspace
   * @throws PermissionException if the connected user does not have the right to delete this transformation
   */
  public void deleteTransformation(String uid) throws NoSuchObjectException, PermissionException;

  /**
   * Method executing a transformation to generate a trace from one or several other.
   * The first operation before the transformation execution is to ensure all involved traces are up to date
   * and make a fusion of them.
   * The resulting trace will be stored in the trace repository as a <code>ITransformedTrace</code> instance
   * with an association on a <code>ITransformationExecution</code> instance referencing the used <code>Transformation</code>.
   * @param trace_uids the uids of the traces to be taken into account (and merged) as data source for the transformation
   * @param transformation_uid the UID of the stored transformation to be executed
   * @param parameters a map containing parameter names as keys and parameter values as values
   * @return the UID of the resulting <code>ITransformedTrace</code> instance
   * @throws NoSuchObjectException if the transformation UID is not found or if any of the source trace UID is not found
   * @throws PermissionException if the connected user does not have the right to access a source trace, the transformation,
   * or to create a trace in this workspace
   * @throws UnsupportedLanguageException if the transformation language is not supported
   * @throws MissingParameterException if a transformation mandatory parameter is not given in the parameters map
   * @throws InvalidParameterException if a transformation parameter does not have the expected type
   * @throws IncompatibleTemporalDomainsException if a the source traces does not share the same temporal domain
   * @throws TransformationRuntimeException if the transformation fails due to a syntax problem or internal error
   */
  public String executePersistentTransformation(String[] trace_uids, String transformation_uid,
      Map<String, Serializable> parameters) throws NoSuchObjectException, PermissionException,
      UnsupportedLanguageException, MissingParameterException, InvalidParameterException,
      IncompatibleTemporalDomainsException, TransformationRuntimeException;

  /**
   * Method executing a transformation to generate a trace from one or several other.
   * The first operation before the transformation execution is to ensure all involved traces are up to date
   * and make a fusion of them.
   * The resulting trace will be not be stored in the trace repository but immediately returned as a <code>ITransformedTrace</code> object
   * associated to a volatile <code>ITransformationExecution</code> instance referencing the used <code>Transformation</code>.
   * The UIDs contained in the returned objects will not be known by the trace repository if requested later.
   * @param trace_uids the uids of the traces to be taken into account (and merged) as data source for the transformation
   * @param transformation_uid the UID of the stored transformation to be executed
   * @param parameters a map containing parameter names as keys and parameter values as values
   * @return the resulting <code>ITransformedTrace</code> instance.
   * @throws NoSuchObjectException if the transformation UID is not found or if any of the source trace UID is not found
   * @throws PermissionException if the connected user does not have the right to access a source trace, the transformation,
   * or to create a trace in this workspace
   * @throws UnsupportedLanguageException if the transformation language is not supported
   * @throws MissingParameterException if a transformation mandatory parameter is not given in the parameters map
   * @throws InvalidParameterException if a transformation parameter does not have the expected type
   * @throws IncompatibleTemporalDomainsException if a the source traces does not share the same temporal domain
   * @throws TransformationRuntimeException if the transformation fails due to a syntax problem or internal error
   */
  public ITransformedTrace executeVolatileTransformation(String[] trace_uids, String transformation_uid,
      Map<String, Serializable> parameters) throws NoSuchObjectException, PermissionException,
      UnsupportedLanguageException, MissingParameterException, InvalidParameterException,
      IncompatibleTemporalDomainsException, TransformationRuntimeException;

  /**
   * Method exporting one or several traces as a text output
   * @param trace_uids the uids of the traces to be exported
   * @param format the identifier of the output format, like ITBSKernel.XML_FORMAT 
   * @return a text stream as a unique string
   * @throws NoSuchObjectException if the query UID is not found or if any of the source trace UID is not found
   * @throws PermissionException if the connected user does not have the right to access a source trace
   * @throws UnsupportedFormatException if the required export format is not supported
   */
  public String exportTraces(String[] trace_uids, String format) throws NoSuchObjectException, PermissionException,
      UnsupportedFormatException;

  /** 
   * Method updating a transformed trace that is persisted in the repository. The same parameter values as those memorized in the 
   * ITransformationExecution instance associated with the ITransformedTrace object are reused. TBS kernels managing the monotony 
   * may only run an incremental transformation to update the transformed trace, if all prerequisites are met.
   * @param trace_uid the UID of the transformed trace to be updated.
   * @throws NoSuchObjectException thrown when the target transformed trace or the requested transformation is not found or if any 
   *         of the source trace does not exist any more.
   * @throws PermissionException thrown when the connected user does not have the right to access a source trace, the transformation,
   *         or to modify the target transformed trace.
   * @throws UnsupportedLanguageException thrown when the transformation language property has been modified and does not match anymore
   *         a supported transformation language.
   * @throws MissingParameterException thrown when the transformation has been modified since the last execution and requires new parameters.
   * @throws InvalidParameterException thrown when the transformation has been modified since the last execution and some old parameter does 
   *         not have the expected type.
   * @throws IncompatibleTemporalDomainsException thrown when any of the source traces have been amended and now does not share the same 
   *         temporal domain .
   * @throws TransformationRuntimeException thrown when the transformation fails due to a syntax problem or internal error
   * @throws NotTransformedTraceException thrown the given trace is not a ITransformedTrace, or if it has been emancipated.
   * @throws DirtySourceTraceException thrown when a source trace is obsolete
   */
  public void updateTransformedTrace(String trace_uid) throws NoSuchObjectException, PermissionException,
      UnsupportedLanguageException, MissingParameterException, InvalidParameterException,
      IncompatibleTemporalDomainsException, TransformationRuntimeException, NotTransformedTraceException,
      DirtySourceTraceException;

  /** 
   * Method used to completely compute anew a transformed trace that is persisted in the repository. The same parameter values as 
   * those memorized in the {@link ITransformationExecution} instance associated with the {@link ITransformedTrace} object are reused.
   * Even if an incremental transformation is possible, the whole transformed trace will be recomputed. The parameters and thrown exceptions 
   * are the same as the {@link ILevel2Features#updateTransformedTrace(String)} method.
   * @param trace_uid the UID of the transformed trace to be updated.
   * @throws NoSuchObjectException thrown when the target transformed trace or the requested transformation is not found or if any 
   *         of the source trace does not exist any more.
   * @throws PermissionException thrown when the connected user does not have the right to access a source trace, the transformation,
   *         or to modify the target transformed trace.
   * @throws UnsupportedLanguageException thrown when the transformation language property has been modified and does not match anymore
   *         a supported transformation language.
   * @throws MissingParameterException thrown when the transformation has been modified since the last execution and requires new parameters.
   * @throws InvalidParameterException thrown when the transformation has been modified since the last execution and some old parameter does 
   *         not have the expected type.
   * @throws IncompatibleTemporalDomainsException thrown when any of the source traces have been amended and now does not share the same 
   *         temporal domain .
   * @throws TransformationRuntimeException thrown when the transformation fails due to a syntax problem or internal error
   * @throws NotTransformedTraceException thrown the given trace is not a ITransformedTrace, or if it has been emancipated.
   * @throws DirtySourceTraceException thrown when a source trace is obsolete
   */
  public void recomputeTransformedTrace(String trace_uid) throws NoSuchObjectException, PermissionException,
      UnsupportedLanguageException, MissingParameterException, InvalidParameterException,
      IncompatibleTemporalDomainsException, TransformationRuntimeException, NotTransformedTraceException,
      DirtySourceTraceException;

}
